﻿#include "qpicturebox.h"

QPictureBox::QPictureBox(QWidget *parent) :
    QOpenGLWidget(parent),background(QColor(255,255,255,255))
{
    data.resize(24);
    data = {
    -1.0f,-1.0f,0.0f,0.0f,
     1.0f,-1.0f,1.0f,0.0f,
     1.0f, 1.0f,1.0f,1.0f,
    -1.0f,-1.0f,0.0f,0.0f,
    -1.0f, 1.0f,0.0f,1.0f,
     1.0f, 1.0f,1.0f,1.0f
    };
    image_data = QImage(100,100,QImage::Format_RGB32);
}

void QPictureBox::setImage(QImage &image)
{
    if(texture) delete texture;
    texture = nullptr;
    image_data = image.mirrored();
}

void QPictureBox::setImage(const QString &filename)
{
    if(texture) delete texture;
    texture = nullptr;
    image_data = QImage(filename).mirrored();
}

void QPictureBox::setScaleType(QPictureBox::Scale_Type x)
{
    image_Scale_Type = x;
}

void QPictureBox::setBackGround(QColor color)
{
    background = color;
}

void QPictureBox::initializeGL()
{
    initializeOpenGLFunctions();
    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex,this);
    const char *vertexShaderSource =
    "#version 330 core\n"
    "layout(location=0)in vec2 aPos;\n"
    "layout(location=1)in vec2 aTexCoord;\n"
    "out vec2 TexCoord;\n"
    "uniform mat4 transform;\n"
    "void main()\n"
    "{\n"
    "gl_Position = transform * vec4(aPos,0.0f,1.0f);\n"
    "TexCoord = aTexCoord;\n"
    "}";
    vshader->compileSourceCode(vertexShaderSource);

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc =
    "#version 330 core\n"
    "out vec4 FragColor;\n"
    "in vec2 TexCoord;\n"
    "uniform sampler2D ourTexture;\n"
    "void main()\n"
    "{FragColor = texture(ourTexture, TexCoord);}";
    fshader->compileSourceCode(fsrc);


    program.addShader(vshader);
    program.addShader(fshader);
    program.bindAttributeLocation("ourTexture",0);
    program.bindAttributeLocation("transform",1);
    program.link();
    program.bind();

    VBO.create();
    texture = new QOpenGLTexture(image_data);
    texture->bind();

    VBO.bind();
    VBO.allocate(data.data(),data.count()*sizeof (GLfloat));

    program.enableAttributeArray(0);
    program.setAttributeBuffer(0,GL_FLOAT,0,2,4*sizeof (GLfloat));

    program.enableAttributeArray(1);
    program.setAttributeBuffer(1,GL_FLOAT,2*sizeof (GLfloat),2,4*sizeof (GLfloat));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

}

void QPictureBox::paintGL()
{
    QMatrix4x4 trans_;
    float scale_im = (float)image_data.width()/(float)image_data.height();
    float scale_form = (float)width()/(float)height();
    switch (image_Scale_Type) {
    case fitXY:
        trans_.ortho(-1.0f,1.0f,-1.0f,1.0f,-1.0f,1.0f);
        break;
    case fitCenter:
        if(scale_im>scale_form)
            trans_.ortho(-1.0f,1.0f,-scale_im/scale_form,scale_im/scale_form,-1.0f,1.0f);
        else
            trans_.ortho(-scale_form/scale_im,scale_form/scale_im,-1.0f,1.0f,-1.0f,1.0f);
        break;
    case CenterCorp:
        if(scale_im>scale_form)
            trans_.ortho(-scale_form/scale_im,scale_form/scale_im,-1.0f,1.0f,-1.0f,1.0f);
        else
            trans_.ortho(-1.0f,1.0f,-scale_im/scale_form,scale_im/scale_form,-1.0f,1.0f);
        break;
        break;
    }
    program.setUniformValue("transform",trans_);
    texture->bind();
    glClearColor((GLfloat)background.red()/255.0,(GLfloat)background.green()/255.0,(GLfloat)background.blue()/255.0,(GLfloat)background.alpha()/255.0);
    glDrawArrays(GL_TRIANGLES,0,data.count());

}
